/*    file: RtpTsMediaCaster.h
 *    desc:
 *   
 * created: 2016-12-22
 *  author: chuanjiang.zh@qq.com
 * company: 
 */ 


#if !defined RTPTSMEDIACASTER_H_
#define RTPTSMEDIACASTER_H_


#include "TsMediaCaster.h"
#include "TThread.h"
#include "TCriticalSection.h"
#include "TByteBuffer.h"
#include "MediaPacketQueue.h"
#include "NetAddress.h"
#include "Socket.h"
#include "TsMuxer.h"
#include "TsCaster.h"
#include "H264PropDetector.h"
#include "NaluJoiner.h"


namespace av
{

typedef std::deque< NetAddress >        NetAddressArray;
typedef std::shared_ptr< TsMuxer >		TsMuxerPtr;


class RtpTsMediaCaster : public TsMediaCaster, public MediaSink, public TsMuxerSink, public comn::Thread
{
public:
	RtpTsMediaCaster();
	virtual ~RtpTsMediaCaster();

	virtual int open(const std::string& ip, uint16_t port, const MediaFormat& fmt);

	virtual void close();

	virtual bool isOpen();

	virtual void setID(int id);

	virtual int getID();

	virtual bool addTarget(const std::string& ip, uint16_t port);

	virtual void removeTarget(const std::string& ip, uint16_t port);

	virtual size_t getTargetCount();

	virtual void removeAllTarget();

	virtual bool write(int type, uint8_t* data, int size, int64_t pts, int duration, int flags);


	virtual void onMediaFormat(const MediaFormat& fmt);

	virtual void onMediaPacket(MediaPacketPtr& pkt);

	virtual void onMediaEvent(int event);


protected:
	virtual int run();
	virtual void doStop();

	virtual void writePacket(uint8_t* data, int size, int64_t pts, int flags);

protected:


	bool openSocket(const std::string& ip, int port);
	void closeSocket();

	void sendPacket(uint8_t* data, int size);

	bool sendPacket(NetAddress& addr, uint8_t* data, int size);

	void timedwait(int ms);

	void writeToPacket(MediaPacket& pkt, int type, uint8_t* data, int size, int64_t pts, int duration, int flags);

	int detectKeyFrame(uint8_t* data, int size);

protected:
	comn::Socket    m_socket;
	comn::ByteBuffer    m_buffer;

	NetAddress	m_addr;
	MediaPacketQueue    m_pktQueue;

	NetAddressArray		m_targets;
	comn::CriticalSection	m_cs;

	int		m_id;

	TsMuxerPtr	m_muxer;
	int		m_delayCount;

	int64_t	m_videoLastPts;
	int64_t m_audioLastPts;

	uint16_t    m_seq;
	uint32_t    m_ssrc;

	uint32_t    m_initTime;

	H264PropDetector	m_propDetector;
	std::shared_ptr< NaluJoiner >	m_naluJoiner;

};


} /* namespace av */


#endif //RTPTSMEDIACASTER_H_

